﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using CampusSite.Models;
using CampusSite.Security;
using Campus.Entities;
using CampusSite.Models.Mail;
using System.Security.Cryptography;
using CampusSite.Support.Extensions;
using BotDetect.Web.Mvc;

namespace CampusSite.Controllers
{

    //[LogonAuthorize]
    [RolActionFilter]
    //[RoleAuthorize(Constantes.RolAdministrador, Constantes.RolResponsable)]
    public class AccountController : Controller
    {
        private readonly IUserRepository userRepository;
        private readonly IResponsableRepository responsableRepository;

		// If you are using Dependency Injection, you can delete the following constructor
        public AccountController() : this(new UserRepository(), new ResponsableRepository())
        {
        }

        public AccountController(IUserRepository userRepository, IResponsableRepository responsableRepository)
        {
            this.userRepository = userRepository;
            this.responsableRepository = responsableRepository;
			
        }

        //
        // GET: /Account/LogOn
        [AllowAnonymous]
        public ActionResult LogOn()
        {
            return View();
        }


        [AllowAnonymous]
        public ActionResult Test()
        {
            return View();
        }

        [HttpPost]
        [AllowAnonymous]        
        public ActionResult Test(string test)
        {
            return View();
        }


        //
        // POST: /Account/LogOn

        [HttpPost]
        [AllowAnonymous]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {            
            if (ModelState.IsValid)
            {

                Campus.Entities.User usuario = userRepository.ValidateUser(model.UserName, model.Password);

                if (usuario !=null)
                {
                    //FormsAuthentication.RedirectFromLoginPage(model.UserName, model.RememberMe);                                       

                    if (!usuario.Confirmado)
                    {
                        ModelState.AddModelError("", "Su usuario no esta activo o confirmado, debera activarlo por medio del link del mail que fue enviado a su casilla de correo.");
                        return View(model);
                    }

                    Session["Usuario"] = usuario;

                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {

                        if (usuario.Rol == Constantes.RolAdministrador)
                        {
                            return RedirectToAction("Index", "Home"); 
                        }
                        {
                            //Si el responsable ya cargo su informacion y la del alumno tiene el registro completo
                            //deberia enviarlo a la pantalla principal o su index
                            //si el responsable cargo No cargo su información, es decir si el responsable NO existe 
                            //se debe deshabilitar la opcion de cargar informacion de los estudiantes para el responsable
                            
                            //return View(viewName: "Bienvenido", model: User.Identity.Name);
                            return RedirectToAction("Inscripcion");
                        }
                    }
                }
                else
                {
                    ModelState.AddModelError("", "El usuario o la clave son incorrectos");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register
        [AllowAnonymous]
        public ActionResult Register()
        {
            if (User.Identity.IsAuthenticated)
            {
                FormsAuthentication.SignOut();                                
            }            
            return View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        [AllowAnonymous]
        [CaptchaValidation("CaptchaCode", "ExampleCaptcha", "Codigo CAPTCHA Incorrecto!")]
        public ActionResult Register(RegisterModel model)
        {

            
            if (ModelState.IsValid)
            {
                try
                {

                    if (User.Identity.IsAuthenticated)
                    {
                        ModelState.AddModelError("", "Ud. ya tiene usuario. No puede Crear-Registrar un nuevo usuario. Si Ud. esta seguro que no tiene usuario, asegurese de cerrar la sesión iniciada.");
                        return View();
                    }
                        
                    else
                    { 
                        User usuario = userRepository.CreateUser(model.UserName, model.Password, false);

                        FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
                        Mail mail = new Mail();

                        userRepository.Save();
                        mail.Send(usuario);
                        return View(viewName: "ConfirmeUsuarioMail", model: User.Identity.Name);
                    }                    
                }
                catch (Exception e)
                {
                    ModelState.AddModelError("", e.Message);

                    return View();
                }
                              
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        
      

        //public ActionResult Bienvenido()
        //{        
        //    return View();
        //}
       
        [AllowAnonymous]
        public ActionResult Bienvenido(string id)
        {
            byte[] usuarioEncriptado = StringExtensions.GetBytesFromStringSeparetedByGuion(id);
            
            string usuario = MiRijndael.Desencriptar(usuarioEncriptado);

            User user = userRepository.FindByName(usuario);

            user.Confirmado = true;

            userRepository.InsertOrUpdate(user);
            userRepository.Save();

            ViewBag.NombreUsuario = user.UserName;
            return View();
        }

        [RoleAuthorize(Constantes.RolResponsable)]
        public ActionResult Inscripcion()
        {
            ViewModels.ResponsableVM responsableVM = SetearResponsableVM();

            return View(responsableVM);
        }

        private ViewModels.ResponsableVM SetearResponsableVM()
        {
            Responsable responsable = responsableRepository.FindByUser(User.Identity.Name);

            ViewModels.ResponsableVM responsableVM = new ViewModels.ResponsableVM();

            responsableVM.UsuarioTieneResponsable = (responsable != null);
            if (responsable!= null && responsable.Estudiantes != null && responsable.Estudiantes.Count > 0)
            {
                responsableVM.ResponsableRegistroAlumnos = true;

                responsableVM.PresentoCertificadoMedico = responsable.Estudiantes.Any(e => e.Documentacion != null && e.Documentacion.CertificadoMedico);
                responsableVM.PresentoFichaFirmada = responsable.Estudiantes.Any(e => e.Documentacion != null && e.Documentacion.FichaFirmada);
            }
            else
            {
                responsableVM.PresentoCertificadoMedico = false;
                responsableVM.PresentoFichaFirmada = false;
                responsableVM.ResponsableRegistroAlumnos = false;
            }

            if (responsable != null)
            {
                responsableVM.Estado = (Constantes.EstadosResponsable)responsable.Estado;
                responsableVM.responsableId = responsable.ResponsableId;
            }
            else
            {

                responsableVM.Estado =  CampusSite.Models.Constantes.EstadosResponsable.Inicial;
                responsableVM.responsableId = -1;            
            }

            return responsableVM;


        }
        
        [RoleAuthorize(Constantes.RolResponsable)]
        public ActionResult ConfirmarInscripcion()
        {

            ViewModels.ResponsableVM responsableVM = SetearResponsableVM();

            if (responsableVM != null && responsableVM.ResponsableRegistroAlumnos && 
                responsableVM.UsuarioTieneResponsable 
                )
            {
               Responsable responsable = responsableRepository.Find(responsableVM.responsableId);
               if (responsable.Estado != (int) Constantes.EstadosResponsable.Aprobado)
               {
                   responsable.Estado = (int)Constantes.EstadosResponsable.EsperandoAprobacion;
                   responsable.FechaEsperandoAprobacion = DateTime.Now;
                   responsableRepository.Save();
                   responsableVM.Estado = Constantes.EstadosResponsable.EsperandoAprobacion;
               }
            }
            
            return View("Inscripcion",responsableVM);
        }

        //
        // GET: /Account/ChangePassword

        
        public ActionResult ChangePassword()
        {
            return View();
        }

        //
        // POST: /Account/ChangePassword

        
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded = false;
                try
                {
                    if (User.Identity.IsAuthenticated)
                    {
                        Campus.Entities.User usuario = userRepository.FindByName(User.Identity.Name);

                        if (model.OldPassword != usuario.Password)
                        {
                            ModelState.AddModelError("", "Las clave anterior no es correcta");
                            return View();
                        }
                        if (model.NewPassword == model.ConfirmPassword)
                        {
                            usuario.Password = model.NewPassword;
                            userRepository.Save();
                            changePasswordSucceeded = true;
                        }
                        else                        
                            ModelState.AddModelError("", "Las claves no coinciden");
                    }
                    else
                    {
                        ModelState.AddModelError("", "El usuario no esta autenticado");
                    }
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "La contraseña actual es incorrecta o la nueva es invalida");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    }
}
